/*
	Связь с платой мощности
*/

#include "defines.h"


U64 powerTime=0;
U64 powerRecvTime=0;

//Буфер приема
U8 	power_recv_buffer[255];
U8 	power_recv_bufsize=0;

//Конечный автомат
PowerStateT powerState = POWER_IDLE;

//Накопленные данные
PowerStoreT powerStore;

/*
	Настройка
*/
void power_init(void)
{
	//настройка UART
	power_uart_init();
	//Настройка RTS
	POWER_RTS_PORT->FIODIR|=(1<<POWER_RTS_PIN);
	POWER_RTS_HIGH;
}

/*
	Процесс опроса платы мощности
*/
void power_prc(void)
{
	PowerT power;
	switch (powerState)
	{
		//--------------------------------------------
		//Ждем-с
		case POWER_IDLE:
		{
			//Пора измерять?
			if (SystemTick-powerTime>=POWER_INTERVAL)
			{
				//printf("Start power request\r\n");
				//RTS low и ждем первого байта
				power_recv_bufsize=0;
				POWER_RTS_LOW;
				powerState = POWER_WAIT_FIRST_BYTE;
				powerRecvTime = SystemTick;
			}
			break;
		}
		//--------------------------------------------
		//Ждем приема первого байта
		case POWER_WAIT_FIRST_BYTE:
		{
			//Приняли данные
			if (power_recv_bufsize>=1)
			{
				POWER_RTS_HIGH;
				//Ждем остальных данных
				powerState = POWER_WAIT_DATA;
				powerRecvTime=SystemTick;
			
			}
			//Не слишком долго ли ждем?
			else
			{
				//Таймаут!!!
				if (SystemTick-powerRecvTime>=POWER_FIRSTBYTE_TIMEOUT)
				{
					//printf("Power first byte timeout\r\n");
					POWER_RTS_HIGH;
					powerTime = SystemTick;
					powerState = POWER_IDLE;		
				}
			}
			break;
		}
		//--------------------------------------------
		//Ждем приема всех данных
		case POWER_WAIT_DATA:
		{
			//Приняли данные
			if (power_recv_bufsize>=sizeof(PowerT))
			{
				//накапливаем данные
				memcpy((U8 *)&power,power_recv_buffer,sizeof(power));
				powerStore.powerFull+=power.powerFull;
				powerStore.powerActive+=power.powerActive;
				powerStore.voltageA+=power.voltageA;
				powerStore.currentA+=power.currentA;
				powerStore.voltageB+=power.voltageB;
				powerStore.currentB+=power.currentB;
				powerStore.voltageC+=power.voltageC;
				powerStore.currentC+=power.currentC;
				
				//Увеличиваем индекс
				powerStore.count++;
				
				//printf("Power Data OK\r\n");
			}
			//Пока нет данных
			else
			{
				//Таймаут!!! 
				if(SystemTick-powerRecvTime>=POWER_TIMEOUT)
				{
					//printf("Power data timeout\r\n");
					powerTime = SystemTick;
					powerState = POWER_IDLE;		
				}
			}
			break;
		}
			
			
	}	
	
}

/*
	Найстройка интерфейса
*/
void power_uart_init(void)
{

	//Это для UART1
	//LPC_SC->PCONP |= ((1 << 4) | (1 << 15)); /* enable power to UART1 & IOCON   */
	LPC_SC->PCONP |= ((1 << 4));/* enable power to UART1 & IOCON   */
  LPC_PINCON->PINSEL4 |=  (2 << 0);        /* Pin P2.0 used as TXD1           */
  LPC_PINCON->PINSEL4 |=  (2 << 2);        /* Pin P2.1 used as RXD1           */
	
	//настройка 
	POWER_UART->LCR    = 0x83;                     /* 8 bits, no Parity, 1 Stop bit   */
  POWER_UART->DLL    = 18;                        /* 57600 Baud Rate @ 25.0 MHZ PCLK*/
  POWER_UART->FDR    = 0x21;                     /* FR 1,507, DIVADDVAL=1, MULVAL=2 */
  POWER_UART->DLM    = 0;                        /* High divisor latch = 0          */
  POWER_UART->LCR    = 0x03;                     /* DLAB = 0                        */
	
	POWER_UART->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */

	//Настройка перерываний
	NVIC_EnableIRQ(UART1_IRQn);
	POWER_UART->IER = (0x01);
	
}

/*
	Обработчик прерываний - при приеме символов
*/

void UART1_IRQHandler (void) 
{
	U8 IIRValue;

	//Определяем из за чего прерывание
  IIRValue = POWER_UART->IIR;
  IIRValue >>= 1;			
  IIRValue &= 0x07;		
	
	//Нас интересует только прием символа
	if (IIRValue & 0x02)
	{
		//Переполнение?	
		if (power_recv_bufsize>=sizeof(power_recv_buffer))
			power_recv_bufsize=0;
		
		//Принимаем данные
		power_recv_buffer[power_recv_bufsize++] = POWER_UART->RBR;
	}
}

void power_send_char(U8 ch)
{
 while (!(POWER_UART->LSR & 0x20))
	 ;
  POWER_UART->THR = ch;
}

/*
	Запрос среднего значения мощности
*/
PowerT power_get_average(void)
{
	PowerT power;
	
	power.powerFull = (U16)(powerStore.powerFull/powerStore.count);
	power.powerActive =(U16)(powerStore.powerActive/powerStore.count);
	power.voltageA = (U16)(powerStore.voltageA/powerStore.count);
	power.currentA =(U16)(powerStore.currentA/powerStore.count);
	power.voltageB = (U16)(powerStore.voltageB/powerStore.count);
	power.currentB =(U16)(powerStore.currentB/powerStore.count);
	power.voltageC = (U16)(powerStore.voltageC/powerStore.count);
	power.currentC =(U16)(powerStore.currentC/powerStore.count);
	
	//Обнуляем
	memset((U8 *)&powerStore,0x00,sizeof(powerStore));
	
	return power;
}



